#include "stdafx.h"

#include <todaycmn.h>
#include "TodaySettings.h"
#include "TodayHost.h"
#include "logger.h"
#include "general.h"

#include "PatchingUtils.h"
#include "IPageChangeHooker.h"
#include "TF2DHooker.h"
#include "TF3DHooker.h"
#include "LuaHooker.h"


#define IDT_TIMER1 1

#define WM_TODAY_RELOADCONFIG (WM_USER + 250)
#define WM_MANILA_TODAY_TAB_TERMINATE (WM_USER + 24)


BOOL manila2D = false;

BOOL isAttached = false;
TCHAR szWindowClass2[] =  { L"MySuperCollllClass" };	

HANDLE moduleHandle;
WNDPROC prevMainWndProc;
WNDPROC prevButtonsWndProc;

BOOL isControlCreated = false;

HWND myTodayHWND;
HWND bntHWND;

DWORD processId;

TodayHost* host;
Logger* logger;

BOOL loaded = false;

TODAYTABSETTINGS settings;

HANDLE runningEvent;

bool isMtpActive = false;


IPageChangeHooker* hooker;

void PageChangeCallback(bool isActive)
{
	isMtpActive = isActive;
	ShowWindow(myTodayHWND, isMtpActive ? SW_SHOW : SW_HIDE);
}

BOOL SortPredicate(TODAYLISTITEM i1, TODAYLISTITEM i2)
{
	return i1.dwOrder < i2.dwOrder;
}

bool IsInLandscapeMode()
{
	HKEY hKey;
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"System\\GDI\\Rotation", NULL, KEY_QUERY_VALUE, &hKey);
	DWORD data;
	DWORD dataLen = sizeof(DWORD);
	DWORD result = RegQueryValueEx(hKey, L"Angle", 0, 0, (BYTE*)&data, &dataLen);
	RegCloseKey(hKey);
	return data == 90 || data == 270;
}

void InitHostWindowSize()
{
	HWND wnd = hooker->GetManilaWindow();
	RECT parrentRect;
	GetClientRect(wnd, &parrentRect);
	
	int newHeight = 0;
	if (IsInLandscapeMode())
	{
		newHeight = settings.fOverrideTabHeight && settings.TabHeightLandscape != 0 ? settings.TabHeightLandscape : parrentRect.bottom - parrentRect.top - 50 + 4;
	}
	else
	{
		newHeight = settings.fOverrideTabHeight && settings.TabHeight != 0 ? settings.TabHeight : parrentRect.bottom - parrentRect.top - 50 - 50 + 4;
	}
	SetWindowPos(myTodayHWND, HWND_TOP, 0, 0, parrentRect.right, newHeight, 0);
}

void InitToday()
{
	list<TODAYLISTITEM>*plugins = GetAvailablePlugins();
	plugins->sort(SortPredicate);

	settings = GetMainSettings();
	logger->Log(L"Settins.ActivePage: %s", settings.szActivePage);
	
	InitHostWindowSize();

	logger->Log(L"Setting background: %s", settings.szBackgroundPath);
	host->SetBackground(settings.szBackgroundPath);

	list<TODAYLISTITEM>::iterator i;
	for (i = plugins->begin(); i!= plugins->end(); i++)
	{
		if (i->tlit == 4 && i->fEnabled)
		{
			logger->Log(L"Loading plugin: %s. FileName: %s", i->szName, i->szDLLPath);
			host->LoadPlugin(*i);
		}
	}
}

LRESULT CALLBACK TodayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_TODAY_RELOADCONFIG:
		host->UnloadAllPlugins();
		InitToday();
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return host->MessageHandler(hWnd, message, wParam, lParam);
	}
	return 0;
}

ATOM MyRegisterClassChild(HINSTANCE hInstance)
{
	WNDCLASS wcex;
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= TodayWndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= 0;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= CreateSolidBrush(RGB(0, 0, 0));
	wcex.lpszMenuName	= 0;
	wcex.lpszClassName	= szWindowClass2;

	return RegisterClass(&wcex);
}


LRESULT CALLBACK MainWndProcRepl(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (!isControlCreated)
	{
		isControlCreated = true;
		
		HWND wnd = hooker->GetManilaWindow();
		RECT parrentRect;
		GetClientRect(wnd, &parrentRect);
				
		myTodayHWND = CreateWindow(szWindowClass2, L"MyTitle", WS_CHILD,
			0, 0, parrentRect.right, parrentRect.bottom - parrentRect.top - 50 - 50 + 4, wnd, NULL, (HINSTANCE)moduleHandle, NULL);

		host = new TodayHost(myTodayHWND);
		InitToday();

		hooker->Initialize(logger, &settings);
		hooker->Hook(PageChangeCallback);
		
		runningEvent = CreateEvent(0, false, false, L"ManilaTodayPageStartup");
	}
	if (message == WM_TODAY_RELOADCONFIG)
	{
		logger->Log(L"Reloading configuraiton...");
		PostMessage(myTodayHWND, WM_TODAY_RELOADCONFIG, 0, 0);
		return 0;
	}

	if (message == WM_KEYDOWN || message == WM_KEYUP ||  message == WM_CHAR)
	{
		if (isMtpActive && host->HasSelectedPlugin())
		{
			return SendMessage(myTodayHWND, message, wParam, lParam);
		}
		else
		{
			if (isMtpActive && (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_RETURN))
			{
				return SendMessage(myTodayHWND, message, wParam, lParam);
			}
			else
			{
				return CallWindowProc(prevMainWndProc, hWnd, message, wParam, lParam);
			}
		}
	}

	if (message == WM_SETTINGCHANGE && SETTINGCHANGE_RESET == wParam)
	{
		InitHostWindowSize();
	}

	if (message == WM_MANILA_TODAY_TAB_TERMINATE)
	{
		hooker->UnHook();
		host->UnloadAllPlugins();
		delete host;
		DestroyWindow(myTodayHWND);
		//UnregisterClass(szWindowClass2, (HINSTANCE)moduleHandle);
		//CloseHandle(runningEvent);
		//FreeLibrary((HMODULE)moduleHandle);
		return 0;
	}
	
	return CallWindowProc(prevMainWndProc, hWnd, message, wParam, lParam);
}


BOOL APIENTRY DllMain( HANDLE hModule,  DWORD  ul_reason_for_call,   LPVOID lpReserved )
{
	return TRUE;
}


__declspec(dllexport) void RunIt()
{
	if (loaded)
		return;
	loaded = true;

	DebugBreak();

	TCHAR logPath[MAX_PATH];
	FormatSpecialFolderPath(CSIDL_PROGRAM_FILES, L"ManilaTodayPage\\log.txt", logPath);
	logger = new Logger(logPath);

	isAttached = true;
	moduleHandle = GetModuleHandle(0);

	ATOM result = MyRegisterClassChild((HINSTANCE)moduleHandle);

	logger->Log(L"About to create hooker, Type  %d", manila2D);

	//hooker = LuaHooker::get_Instance();
	hooker = manila2D ? (IPageChangeHooker*)TF2DHooker::get_Instance() : TF3DHooker::get_Instance();
	logger->Log(L"Hooker is created");

	HWND wnd = hooker->GetManilaWindow();

	logger->Log(L"Manila window: %x", wnd);

	GetWindowThreadProcessId(wnd, &processId);

	prevMainWndProc = (WNDPROC)SetWindowLong(wnd, GWL_WNDPROC, (LONG_PTR)MainWndProcRepl);
}

